package com.example.project.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.Collection;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

/**
 * 线程池工具类 - 提供全面的线程池管理和任务执行功能
 * 
 * 功能特性：
 * 1. 线程池创建和管理
 * 2. 异步任务执行（有返回值和无返回值）
 * 3. 批量任务并行处理
 * 4. 任务超时控制
 * 5. 异常处理和日志记录
 * 6. 线程池状态监控
 * 7. 优雅关闭机制
 * 8. 任务统计和健康检查
 * 
 * @author ruoyi
 */
public class ThreadPoolUtils {

	/** 日志记录器 */
	private static final Logger logger = LoggerFactory.getLogger(ThreadPoolUtils.class);

	// 默认线程池配置常量
	/** 默认核心线程数 */
	private static final int DEFAULT_CORE_POOL_SIZE = 10;
	/** 默认最大线程数 */
	private static final int DEFAULT_MAX_POOL_SIZE = 50;
	/** 默认队列容量 */
	private static final int DEFAULT_QUEUE_CAPACITY = 100;
	/** 默认线程空闲时间（秒） */
	private static final int DEFAULT_KEEP_ALIVE_SECONDS = 60;

	// 任务统计计数器
	/** 总任务计数器 */
	private static final AtomicInteger taskCounter = new AtomicInteger(0);
	/** 已完成任务计数器 */
	private static final AtomicInteger completedTaskCounter = new AtomicInteger(0);
	/** 失败任务计数器 */
	private static final AtomicInteger failedTaskCounter = new AtomicInteger(0);

	/**
	 * 创建自定义线程池
	 * 
	 * @param poolName 线程池名称，用于线程命名前缀
	 * @param corePoolSize 核心线程数
	 * @param maxPoolSize 最大线程数
	 * @param queueCapacity 队列容量
	 * @param keepAliveSeconds 线程空闲时间（秒）
	 * @return 配置好的ThreadPoolTaskExecutor实例
	 * @throws IllegalArgumentException 如果参数不合法
	 */
	public static ThreadPoolTaskExecutor createThreadPool(String poolName, int corePoolSize, int maxPoolSize,
			int queueCapacity, int keepAliveSeconds) {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setCorePoolSize(corePoolSize);
		executor.setMaxPoolSize(maxPoolSize);
		executor.setQueueCapacity(queueCapacity);
		executor.setKeepAliveSeconds(keepAliveSeconds);
		executor.setThreadNamePrefix(poolName + "-");
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		executor.setWaitForTasksToCompleteOnShutdown(true);
		executor.setAwaitTerminationSeconds(60);
		executor.initialize();

		logger.info("创建线程池: {}, 核心线程数: {}, 最大线程数: {}, 队列容量: {}", poolName, corePoolSize, maxPoolSize, queueCapacity);
		return executor;
	}

	/**
	 * 创建默认线程池
	 * 
	 * @param poolName 线程池名称，用于线程命名前缀
	 * @return 使用默认配置的ThreadPoolTaskExecutor实例
	 * @see #DEFAULT_CORE_POOL_SIZE
	 * @see #DEFAULT_MAX_POOL_SIZE
	 * @see #DEFAULT_QUEUE_CAPACITY
	 * @see #DEFAULT_KEEP_ALIVE_SECONDS
	 */
	public static ThreadPoolTaskExecutor createDefaultThreadPool(String poolName) {
		return createThreadPool(poolName, DEFAULT_CORE_POOL_SIZE, DEFAULT_MAX_POOL_SIZE, DEFAULT_QUEUE_CAPACITY,
				DEFAULT_KEEP_ALIVE_SECONDS);
	}

	/**
	 * 异步执行任务（无返回值）
	 * 
	 * @param executor 线程池执行器
	 * @param task 要执行的任务
	 * @throws NullPointerException 如果executor或task为null
	 */
	public static void executeAsync(ThreadPoolTaskExecutor executor, Runnable task) {
		executeAsync(executor, task, null);
	}

	/**
	 * 异步执行任务（带异常处理）
	 * 
	 * @param executor 线程池执行器
	 * @param task 要执行的任务
	 * @param exceptionHandler 异常处理器，可以为null
	 * @throws NullPointerException 如果executor或task为null
	 */
	public static void executeAsync(ThreadPoolTaskExecutor executor, Runnable task,
			Consumer<Exception> exceptionHandler) {
		int taskId = taskCounter.incrementAndGet();
		logger.debug("开始执行异步任务 ID: {}", taskId);

		executor.execute(() -> {
			try {
				task.run();
				completedTaskCounter.incrementAndGet();
				logger.debug("异步任务 ID: {} 执行完成", taskId);
			} catch (Exception e) {
				failedTaskCounter.incrementAndGet();
				logger.error("异步任务 ID: {} 执行失败", taskId, e);
				if (exceptionHandler != null) {
					exceptionHandler.accept(e);
				}
			}
		});
	}

	/**
	 * 异步执行任务（有返回值）
	 * 
	 * @param <T> 任务返回类型
	 * @param executor 线程池执行器
	 * @param task 要执行的任务
	 * @return CompletableFuture对象，用于获取任务结果
	 * @throws NullPointerException 如果executor或task为null
	 */
	public static <T> CompletableFuture<T> submitAsync(ThreadPoolTaskExecutor executor, Callable<T> task) {
		return submitAsync(executor, task, null);
	}

	/**
	 * 异步执行任务（有返回值，带异常处理）
	 * 
	 * @param <T> 任务返回类型
	 * @param executor 线程池执行器
	 * @param task 要执行的任务
	 * @param exceptionHandler 异常处理器，可以为null
	 * @return CompletableFuture对象，用于获取任务结果
	 * @throws NullPointerException 如果executor或task为null
	 */
	public static <T> CompletableFuture<T> submitAsync(ThreadPoolTaskExecutor executor, Callable<T> task,
			Consumer<Exception> exceptionHandler) {
		int taskId = taskCounter.incrementAndGet();
		logger.debug("开始提交异步任务 ID: {}", taskId);

		return CompletableFuture.supplyAsync(() -> {
			try {
				T result = task.call();
				completedTaskCounter.incrementAndGet();
				logger.debug("异步任务 ID: {} 执行完成", taskId);
				return result;
			} catch (Exception e) {
				failedTaskCounter.incrementAndGet();
				logger.error("异步任务 ID: {} 执行失败", taskId, e);
				if (exceptionHandler != null) {
					exceptionHandler.accept(e);
				}
				throw new CompletionException(e);
			}
		}, executor);
	}

	/**
	 * 批量执行任务
	 * 
	 * @param <T> 泛型参数（用于类型兼容）
	 * @param executor 线程池执行器
	 * @param tasks 任务集合
	 * @return CompletableFuture对象，当所有任务完成时完成
	 * @throws NullPointerException 如果executor或tasks为null
	 */
	public static <T> CompletableFuture<Void> executeBatch(ThreadPoolTaskExecutor executor, Iterable<Runnable> tasks) {
		return executeBatch(executor, tasks, null);
	}

	/**
	 * 批量执行任务（带异常处理）
	 * 
	 * @param <T> 泛型参数（用于类型兼容）
	 * @param executor 线程池执行器
	 * @param tasks 任务集合
	 * @param exceptionHandler 异常处理器，可以为null
	 * @return CompletableFuture对象，当所有任务完成时完成
	 * @throws NullPointerException 如果executor或tasks为null
	 */
	public static <T> CompletableFuture<Void> executeBatch(ThreadPoolTaskExecutor executor, Iterable<Runnable> tasks,
			Consumer<Exception> exceptionHandler) {
		CompletableFuture<?>[] futures = new CompletableFuture<?>[getIterableSize(tasks)];
		int index = 0;

		for (Runnable task : tasks) {
			futures[index++] = submitAsync(executor, () -> {
				task.run();
				return null;
			}, exceptionHandler);
		}

		return CompletableFuture.allOf(futures);
	}

	/**
	 * 带超时的任务执行
	 * 
	 * @param <T> 任务返回类型
	 * @param executor 线程池执行器
	 * @param task 要执行的任务
	 * @param timeout 超时时间
	 * @param timeUnit 时间单位
	 * @return 任务执行结果
	 * @throws TimeoutException 如果任务执行超时
	 * @throws RuntimeException 如果任务被中断或执行异常
	 * @throws NullPointerException 如果executor或task为null
	 */
	public static <T> T executeWithTimeout(ThreadPoolTaskExecutor executor, Callable<T> task, long timeout,
			TimeUnit timeUnit) throws TimeoutException {
		Future<T> future = executor.submit(task);
		try {
			return future.get(timeout, timeUnit);
		} catch (InterruptedException e) {
			future.cancel(true);
			Thread.currentThread().interrupt();
			throw new RuntimeException("任务被中断", e);
		} catch (ExecutionException e) {
			throw new RuntimeException("任务执行异常", e.getCause());
		} catch (TimeoutException e) {
			future.cancel(true);
			throw e;
		}
	}

	/**
	 * 获取线程池状态信息
	 * 
	 * @param executor 线程池执行器
	 * @return 线程池状态信息字符串
	 * @throws NullPointerException 如果executor为null
	 */
	public static String getThreadPoolStatus(ThreadPoolTaskExecutor executor) {
		ThreadPoolExecutor threadPoolExecutor = executor.getThreadPoolExecutor();
		return String.format("线程池状态: 活跃线程数=%d, 核心线程数=%d, 最大线程数=%d, 队列大小=%d, 已完成任务数=%d, 总任务数=%d",
				threadPoolExecutor.getActiveCount(), threadPoolExecutor.getCorePoolSize(),
				threadPoolExecutor.getMaximumPoolSize(), threadPoolExecutor.getQueue().size(),
				threadPoolExecutor.getCompletedTaskCount(), threadPoolExecutor.getTaskCount());
	}

	/**
	 * 获取任务统计信息
	 * 
	 * @return 任务统计信息字符串，包含总任务数、成功数、失败数和成功率
	 */
	public static String getTaskStatistics() {
		return String.format("任务统计: 总任务数=%d, 成功数=%d, 失败数=%d, 成功率=%.2f%%", taskCounter.get(), completedTaskCounter.get(),
				failedTaskCounter.get(),
				taskCounter.get() == 0 ? 0 : (completedTaskCounter.get() * 100.0 / taskCounter.get()));
	}

	/**
	 * 安全关闭线程池
	 * 
	 * 该方法会先尝试优雅关闭，等待正在执行的任务完成。
	 * 如果超时（60秒），则强制关闭线程池。
	 * 
	 * @param executor 要关闭的线程池执行器
	 */
	public static void shutdownGracefully(ThreadPoolTaskExecutor executor) {
		if (executor != null) {
			logger.info("开始优雅关闭线程池...");
			executor.shutdown();
			try {
				if (!executor.getThreadPoolExecutor().awaitTermination(60, TimeUnit.SECONDS)) {
					logger.warn("线程池未在指定时间内关闭，强制关闭");
					executor.getThreadPoolExecutor().shutdownNow();
				}
			} catch (InterruptedException e) {
				executor.getThreadPoolExecutor().shutdownNow();
				Thread.currentThread().interrupt();
			}
			logger.info("线程池已关闭");
		}
	}

	/**
	 * 重置任务计数器
	 * 
	 * 将总任务数、成功数和失败数计数器重置为0
	 */
	public static void resetCounters() {
		taskCounter.set(0);
		completedTaskCounter.set(0);
		failedTaskCounter.set(0);
		logger.info("任务计数器已重置");
	}

	/**
	 * 检查线程池是否健康
	 * 
	 * 线程池健康的标准：未关闭、未正在关闭、未已终止
	 * 
	 * @param executor 要检查的线程池执行器
	 * @return 如果线程池健康返回true，否则返回false
	 * @throws NullPointerException 如果executor为null
	 */
	public static boolean isHealthy(ThreadPoolTaskExecutor executor) {
		ThreadPoolExecutor threadPoolExecutor = executor.getThreadPoolExecutor();
		return !threadPoolExecutor.isShutdown() && !threadPoolExecutor.isTerminating()
				&& !threadPoolExecutor.isTerminated();
	}

	/**
	 * 获取可迭代对象的大小
	 */
	private static int getIterableSize(Iterable<?> iterable) {
		if (iterable instanceof Collection) {
			return ((Collection<?>) iterable).size();
		}
		int size = 0;
		for (Object item : iterable) {
			size++;
		}
		return size;
	}
}